import * as THREE from "three";
import { Component, SketchBase } from "fast-three-sketch";
import { shelfManager } from "../objects/ShelfManager";
import { CargoPoint, Shelf } from "../objects/Shelf";
import { shelf_config, ShelfType } from "../config/shelf_config";
import { Cargo } from "../objects/Cargo";

/**
 * 仓库组件
 */
export class Repertory extends Component {

    shelfManager = shelfManager;

    object: THREE.Object3D;

    constructor ( sketch: SketchBase ) {

        super( sketch );

        this.object = new THREE.Object3D();

        sketch.addUpdatable( this );

        sketch.add( this.object );

    }

    update ( sketch: SketchBase ): void {

        const shelfList = this.shelfManager.shelfList;
        const delta = sketch.getDelta();
        shelfList.forEach( shelf => {
            shelf.update( delta );
        } );

    }

    createShelf ( name: string, type: ShelfType, position = new THREE.Vector3() ) {

        const shelf = new Shelf( name );

        const data = shelf_config[ type ] || shelf_config[ "default" ];

        shelf.init( data.length, data.width, data.layerNumber, data.layerHeight, data.firstLayerHeight, data.pointNumber );

        shelf.setPosition( position.x, position.y, position.z );

        this.object.add( shelf.object );

        return shelf;
    }

    removeShelf () { }

    /**
     * 向仓库中添加货物，如果放置点不存在，则依次从第一个货架开始寻找放置点
     * @param cargo 货物
     * @param cargoPoint 货物放置点
     */
    addCargo ( cargo: Cargo, cargoPoint?: CargoPoint ) {

        const shelfList = this.shelfManager.shelfList;

        if ( cargoPoint !== undefined ) {

            for ( let i = 0; i < shelfList.length; i++ ) {

                const shelf = shelfList[ i ];

                if ( cargoPoint.shelf === shelf ) {

                    return shelf.addCargo( cargo, cargoPoint );

                }

            }

        } else {

            for ( let i = 0; i < shelfList.length; i++ ) {

                const shelf = shelfList[ i ];

                const result = shelf.addCargo( cargo, cargoPoint );

                if ( result === true ) {
                    return result;
                }

            }
        }

        return false;
    }

    removeCargo ( cargo: Cargo ) {
        cargo.removeFromShelf();
    }

    getAllCargos () {

        const allCargos = [];

        const shelfList = this.shelfManager.shelfList;

        shelfList.forEach( shelf => {

            allCargos.push( ...shelf.cargos );

        } );

        return allCargos;

    }

    getAllCargoObjects () {

        const allCargoObjects = [];

        const shelfList = this.shelfManager.shelfList;

        shelfList.forEach( shelf => {

            shelf.cargos.forEach( cargo => {

                allCargoObjects.push( cargo.object );

            } );

        } );

        return allCargoObjects;
    }

    getAllCargoPoints () { }

}
